using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class PlayerMoveController : MonoBehaviour
{
    private float speed;
    private CharacterController controller;
    public Vector3 moveDirection;//人物移动方向
    private AudioSource _audioSource;
    
    [Header("玩家属性")]
    [Tooltip("移动速度")]public float walkSpeed;//行走速度
    [Tooltip("奔跑移动速度")]public float runSpeed;//奔跑速度
    [Tooltip("下蹲移动动速度")]public float crouchSpeed;//下蹲速度
    
    [Tooltip("跳跃的力")]public float jumpForce;//跳跃力
    [Tooltip("下落的力")]public float fallForce;//下落力
    [Tooltip("下蹲时的玩家高度")]public float crouchHeight;//下蹲高度
    [Tooltip("站立时的玩家高度")]public float standHeight;//站立高度
    
    [Header("键位设置")]
    [Tooltip("奔跑按键")]public KeyCode runInputName = KeyCode.LeftShift;//奔跑
    [Tooltip("跳跃按键")]public KeyCode jumpInputName = KeyCode.Space;//跳跃
    [Tooltip("下蹲按键")]public KeyCode crouchInputName = KeyCode.LeftControl;//下蹲

    [Header("玩家属性")] 
    public MouveState state;//玩家当前状态
    private CollisionFlags collisionFlags;//碰撞检测
    public bool isWalk;//判断玩家是否在走路状态
    public bool isRun;//判断玩家是否在奔跑状态
    public bool isJump;//判断玩家是否在跳跃状态
    public bool isGround;//判断玩家是否在地面上
    public bool isGanCrouch;//判断玩家是否可以下蹲
    public bool isCrouch;//判断玩家是否在下蹲状态
    
    public LayerMask CrouchLayerMask;//下蹲检测层
    
    [Header("音效")]
    [Tooltip("行走音效")]public AudioClip walkSound;
    [Tooltip("奔跑音效")]public AudioClip RunningSound;

    // Start is called before the first frame update
    void Start()
    {
        controller = GetComponent<CharacterController>();
        _audioSource = GetComponent<AudioSource>();
        walkSpeed = 6f;
        runSpeed = 12f;
        crouchSpeed = 1.5f;
        jumpForce = 0f;
        fallForce = 10f;
        crouchHeight = 1f;
        standHeight = controller.height;
    }

    // Update is called once per frame
    void Update()
    {
        CanCrouch();
        if (Input.GetKey(crouchInputName))
        {
            Crouch(true);
        }
        else
        {
            Crouch(false);
        }
        
        
        Jump();
        PlayerMove();
        PlayerFootSoundSet();
    }
    
    private void PlayerMove()
    {
        float h = Input.GetAxisRaw("Horizontal");
        float v = Input.GetAxisRaw("Vertical");
        
        isRun = Input.GetKey(runInputName);//判断是否按下奔跑键
        isCrouch = Input.GetKey(crouchInputName);//判断是否按下下蹲键
        
        isWalk = (Mathf.Abs(h) > 0 || Mathf.Abs(v) > 0);
        
        // 设置移动状态和速度
        if (isGround)
        {
            if (isRun && !isCrouch)
            {
                state = MouveState.Run;
                speed = runSpeed;//奔跑速度
            }
            else if (isCrouch)
            {
                state = MouveState.Crouch;
                speed = crouchSpeed;//下蹲速度
            }
            else
            {
                state = MouveState.walk;
                speed = walkSpeed;//行走速度
            }
        }
        
        // 计算水平移动方向
        moveDirection = (transform.right * h) + (transform.forward * v);
        if (moveDirection.magnitude > 0)
        {
            moveDirection = moveDirection.normalized;//人物移动方向归一化
        }
    }

    public void Jump()
    {
        if(!isGanCrouch) return;
        
        // 跳跃输入检测
        isJump = Input.GetKeyDown(jumpInputName); // 使用GetKeyDown检测跳跃按键按下的瞬间
        if (isJump && isGround)
        {
            isGround = false;
            state = MouveState.Jump;
            jumpForce = 5f;
        }
        
        // 处理重力和移动
        Vector3 verticalMovement = Vector3.zero;
        
        if (!isGround)
        {
            // 在空中时应用重力
            jumpForce = jumpForce - fallForce * Time.deltaTime;
            verticalMovement.y = jumpForce * Time.deltaTime;
        }
        else
        {
            // 在地面上时应用一个小的向下力，确保与地面良好接触
            verticalMovement.y = -2f * Time.deltaTime;
        }
        
        // 合并水平和垂直移动向量
        Vector3 moveVector = moveDirection * speed * Time.deltaTime + verticalMovement;
        
        // 执行移动并获取碰撞信息
        collisionFlags = controller.Move(moveVector);
        
        // 正确检测地面碰撞（使用按位与操作）
        isGround = (collisionFlags & CollisionFlags.Below) != 0;
        
        // 如果回到地面，重置跳跃力
        if (isGround)
        {
            jumpForce = 0f;
        }
    }

    /// <summary>
    /// 判断玩家是否可以下蹲
    /// </summary>
    public void CanCrouch()
    {
        Vector3 sphereLocation = transform.position + Vector3.up * standHeight;//下蹲检测球的半径位置
        Collider[] colliders = Physics.OverlapSphere(sphereLocation, controller.radius, CrouchLayerMask);//下蹲检测层
        isGanCrouch = (colliders.Length == 0);//玩家是否可以下蹲
        // Debug.Log("下蹲检测球数量：" + colliders.Length);
        // Debug.Log("下蹲检测球位置：" + sphereLocation);
        // Debug.Log("下蹲检测球半径：" + controller.radius);
        // Debug.Log("下蹲检测层：" + CrouchLayerMask);
        // Debug.Log("是否可以下蹲：" + isGanCrouch);
    }

    /// <summary>
    /// 下蹲
    /// </summary>
    public void Crouch(bool newCrouch)
    {
        if(!isGanCrouch) return;
        // Debug.Log("下蹲状态：" + isCrouch + "->" + newCrouch);
        isCrouch = newCrouch;
        controller.height = isCrouch ? crouchHeight : standHeight;//根据下蹲状态设置下蹲高度
        controller.center = new Vector3(0, isGanCrouch ? (controller.height / 2) : 0, 0);//根据下蹲状态设置下蹲中心点
        state = MouveState.Crouch;
        
    }

    public void PlayerFootSoundSet()
    {
        if (isGround && moveDirection.sqrMagnitude > 0f)
        {
            // Debug.Log($"播放脚步声音 行走：{isWalk} 奔跑：{isRun} 状态：{state}");
            if (state == MouveState.walk)
            {
                _audioSource.clip = walkSound;
            }
            else if (state == MouveState.Run)
            {
                _audioSource.clip = RunningSound;
            }

            if (!_audioSource.isPlaying)
            {
                _audioSource.Play();
            }
        }
        else
        {
            // Debug.Log("停止脚步声音");
            _audioSource.Stop();
        }
    }
    
    public enum MouveState
    {
        walk,
        Run,
        Jump,
        Crouch
    }
}
